package com.milo.java8;

import com.alibaba.fastjson.JSONObject;
import org.junit.Test;

import java.util.*;

/**
 * @author: Milogenius
 * @create: 2019-04-19 14:10
 * @description:Lambda表达式学习
 **/

public class LambdaTest {

    /**
     * Lambda表达式基本语法
     */
    @Test
    public void test1() {

        LambdaTest tester = new LambdaTest();

        // 类型声明
        MathOperation addition = (int a, int b) -> a + b;

        // 不用类型声明
        MathOperation subtraction = (a, b) -> a - b;

        // 大括号中的返回语句
        MathOperation multiplication = (int a, int b) -> {
            return a * b;
        };

        // 没有大括号及返回语句
        MathOperation division = (int a, int b) -> a / b;

        System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
        System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
        System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
        System.out.println("10 / 5 = " + tester.operate(10, 5, division));

        // 不用括号
        GreetingService greetService1 = message ->
                System.out.println("Hello " + message);

        // 用括号
        GreetingService greetService2 = (message) ->
                System.out.println("Hello " + message);

        greetService1.sayMessage("Runoob");
        greetService2.sayMessage("Google");
    }

    interface MathOperation {
        int operation(int a, int b);
    }

    interface GreetingService {
        void sayMessage(String message);
    }

    private int operate(int a, int b, MathOperation mathOperation) {
        return mathOperation.operation(a, b);
    }


    /**
     * 测试遍历
     */
    @Test
    public void test2() {
        String[] atp = {"Rafael Nadal", "Novak Djokovic",
                "Stanislas Wawrinka",
                "David Ferrer", "Roger Federer",
                "Andy Murray", "Tomas Berdych",
                "Juan Martin Del Potro"};
        List<String> players = Arrays.asList(atp);

        // 以前的循环方式
        System.out.print("\n-------------------------------以前的循环方式------------------");
        for (String player : players) {
            System.out.print("\n" + player + "; ");
        }

        System.out.print("\n-----------------lambda 表达式以及函数操作-----------------------");
        // 使用 lambda 表达式以及函数操作(functional operation)
        players.forEach((player) -> System.out.print("\n" + player + "; "));

        players.forEach((player)-> System.out.println(player));
        System.out.print("\n-----------------------Java 8 中使用双冒号操作符------------------");
        // 在 Java 8 中使用双冒号操作符(double colon operator)
        players.forEach(System.out::println);
    }

    /**
     * Lambda表达式实现多线程
     */
    @Test
    public void test3() {
        // 1.1使用匿名内部类
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello world !");
            }
        }).start();

        // 1.2使用 lambda expression
        new Thread(() -> System.out.println("Hello world !")).start();
        // 2.1使用匿名内部类
        Runnable race1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello world !");
            }
        };

        // 2.2使用 lambda expression
        Runnable race2 = () -> System.out.println("Hello world !");

        // 直接调用 run 方法(没开新线程哦!)
        race1.run();
        race2.run();

    }

    /**
     * 根据name来排序list
     */
    @Test
    public void test4() {
        String[] players = {"Rafael Nadal", "Novak Djokovic",
                "Stanislas Wawrinka", "David Ferrer",
                "Roger Federer", "Andy Murray",
                "Tomas Berdych", "Juan Martin Del Potro",
                "Richard Gasquet", "John Isner"};

        // 1.1 使用匿名内部类根据 name 排序 players
        Arrays.sort(players, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return (s1.compareTo(s2));
            }
        });
        System.out.println(JSONObject.toJSONString(players));

        // 1.2 使用 lambda expression 排序 players
        Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
        Arrays.sort(players, sortByName);
        System.out.println(JSONObject.toJSONString(players));

        // 1.3 也可以采用如下形式:
        Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));
        System.out.println(JSONObject.toJSONString(players));
    }

    /**
     * lambda表达式复制给外部编码
     * <p>1.定义全局变量</p>
     * <p>2.放置到某个对象</p>
     */

    String str = "";

    @Test
    public void test() {
        HashSet<Object> set = new HashSet<>();
        Map<String, String> hashMap = new HashMap<>();
        hashMap.put("111", "aaa");
        hashMap.put("222", "bbb");
        hashMap.put("333", "ccc");
        ArrayList<Map<String, String>> list = new ArrayList<>();
        list.add(hashMap);
        list.stream().forEach(map->{
            map.forEach((k,v)->{
                if (k.equals("111")) {
                    str=v;
                }
            });
        });
        System.out.println(str);
    }

}
